﻿namespace ufida.u9.ait.openapi
{
	using System;
	using System.Collections.Generic;
	using System.Text;
	using ufida.u9.ait.openapi.utils;
    using UFIDA.U9.CBO.FI.DTOs;
    using UFIDA.U9.CBO.Pub.Controller;
    using UFIDA.U9.MO.MO;
    using UFIDA.U9.MO.MOWorkHourBE;
    using UFIDA.U9.MO.SFC.DispatchCompleteOrder;
	using UFIDA.U9.MO.SFC.DispatchOrder;
	using UFSoft.UBF.AopFrame;
    using UFSoft.UBF.Business;
    using UFSoft.UBF.Util.Context;

	/// <summary>
	/// DispatchAndCompleteSV partial 
	/// </summary>	
	public partial class DispatchAndCompleteSV 
	{	
		internal BaseStrategy Select()
		{
			return new DispatchAndCompleteSVImpementStrategy();	
		}		
	}
	
	#region  implement strategy	
	/// <summary>
	/// Impement Implement
	/// 
	/// </summary>	
	internal partial class DispatchAndCompleteSVImpementStrategy : BaseStrategy
	{
		public DispatchAndCompleteSVImpementStrategy() { }

		public override object Do(object obj)
		{						
			DispatchAndCompleteSV bpObj = (DispatchAndCompleteSV)obj;

            try
            {
                if (bpObj.Data == null || bpObj.Data.Count == 0)
                    throw new Exception("传入参数为空");
                List<CopyOfCommonArchiveDataDTOData> retlist = new List<CopyOfCommonArchiveDataDTOData>();

                foreach (var dto in bpObj.Data)
                {
                    DispatchOrderDoc doc = DispatchOrderDoc.Finder.Find($"DocNo='{dto.DocNo}'");
                    DispatchCompleteOrderDoc doc1 = DispatchCompleteOrderDoc.Finder.Find($"DocNo='{dto.DocNo}'");
                    if (doc == null && doc1 == null)
                    {
                        //派工单/派工申报单都没有
                        //校验
                        CheckDTO(dto);
                        //新增并审核派工单
                        doc = CreateDispatch(dto);
                        //新增并审核完工申报单
                        doc1 = CreateComplete(dto);
                        //增加工时维护
                        CreateMOWorkHour(doc1);
                        //处理返回
                        retlist.Add(new CopyOfCommonArchiveDataDTOData()
                        {
                            ID = doc.ID,
                            Code = doc.DocNo,
                        });
                    }
                    else if (doc != null && doc1 == null)
                    {
                        //派工单有,派工申报单没有
                        //校验
                        CheckDTO(dto);
                        //新增并审核完工申报单
                        doc1 = CreateComplete(dto);
                        //增加工时维护
                        CreateMOWorkHour(doc1);
                        //处理返回
                        retlist.Add(new CopyOfCommonArchiveDataDTOData()
                        {
                            ID = doc.ID,
                            Code = doc.DocNo,
                        });
                    }
                    else
                    {
                        //派工单有,派工申报单都有
                        //修改逻辑
                        //throw new AITException(599, $"单号:{dto.DocNo}已经存在,不能生成!");
                        if (doc1.DocState != UFIDA.U9.MO.Enums.DispatchCompleteOrderDocStateEnum.Approved
                            && doc1.DocState != UFIDA.U9.MO.Enums.DispatchCompleteOrderDocStateEnum.Completed)
                        {
                            throw new Exception($"完工申报单[{doc1.DocNo}]状态不为已核准");
                        }
                        //处理返回
                        retlist.Add(new CopyOfCommonArchiveDataDTOData()
                        {
                            ID = doc.ID,
                            Code = doc.DocNo,
                        });
                    }
                }
                return ResultUtils.success(bpObj, bpObj.Data, retlist);
            }
            catch (Exception ex)
            {

                return ResultUtils.error(bpObj, bpObj.Data, ex);
            }
		}

        /// <summary>
        /// 如果完工申报单上存在工时,创建 工时维护 实体
        /// </summary>
        /// <param name="doc1"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void CreateMOWorkHour(DispatchCompleteOrderDoc doc1)
        {
            using(ISession session = Session.Open())
            {
                foreach (var line in doc1.DispatchCompleteOrderDocLines)
                {
                    if (line.RealLaborPrepareHours > 0 || line.RealLaborProcessHours > 0
                        || line.RealMachinePrepareHours > 0 || line.RealMachineProcessHours > 0)
                    {


                        //存在工时,此时创建 工时维护 实体
                        MOWorkHourAITDTOData dto = new MOWorkHourAITDTOData();
                        dto.Org = new CopyOfCommonArchiveDataDTOData { Code = doc1.Org.Code };
                        dto.BusinessDate = doc1.BusinessDate.ToString();
                        dto.SrcDoc = new CopyOfMOSourceDocData()
                        {
                            MOSrcDocType = 12,
                            SrcDoc = new CopyOfBizEntityKeyData() { EntityID = doc1.ID },
                            SrcDocNo = doc1.DocNo,
                            SrcDocLine = new CopyOfBizEntityKeyData() { EntityID = line.ID },
                        };
                        dto.WorkHourUOM = new CopyOfCommonArchiveDataDTOData() { Code = line.HoursUOM.Code };
                        dto.ItemMasterNum = new CopyOfCommonArchiveDataDTOData() { Code = line.MO.ItemMaster.Code };
                        if (doc1.DispatchOrder.WorkCenter != null)
                        {
                            dto.WorkCenter = new CopyOfCommonArchiveDataDTOData() { 
                                Code = doc1.DispatchOrder.WorkCenter.Code 
                            };
                        }
                        dto.SetupLaborHours = line.RealLaborPrepareHours;
                        dto.SetupMachineHours = line.RealMachinePrepareHours;
                        dto.RunLaborHours = line.RealLaborProcessHours;
                        dto.RunMachineHours = line.RealMachineProcessHours;

                        //调用创建方法
                        MOWorkHourBase.CreateMOWorkHour(dto);

                        //工时维护 会累加,所以这里强制刷新回来
                        line.RealLaborPrepareHours = dto.SetupLaborHours;
                        line.RealMachinePrepareHours = dto.SetupMachineHours;
                        line.RealLaborProcessHours = dto.RunLaborHours;
                        line.RealMachineProcessHours = dto.RunMachineHours;
                    }
                }
                session.InList(doc1);
                session.Commit();
            }
            
        }

        /// <summary>
        /// 传入DTO校验
        /// </summary>
        /// <param name="dto"></param>
        /// <exception cref="Exception"></exception>
        private static void CheckDTO(DispatchOrderAITDTOData dto)
        {
            if (dto.DispatchCompleteOrderDocType == null)
                throw new Exception("DispatchCompleteOrderDocType不能为空");
            if (dto.MO == null)
                throw new Exception("MO属性不能为空");
            //上工序未完工下工序不能派工
            MO mo = MO.Finder.Find($"DocNo='{dto.MO.Code}'");
            if (mo == null)
                throw new Exception($"查找生产订单失败,订单号:[{dto.MO.Code}]");

            foreach (var linedto in dto.DispatchOrderDocLines)
            {
                foreach (var operline in mo.MOOperations)
                {
                    if (linedto.MOOperation == operline.OperationNum)
                    {
                        //派工工序==生产订单工序,进行派工数量校验
                        //校验公式 当前派工数量>工序排队数量
                        if (linedto.DispatchQty > operline.QueueQty)
                        {
                            throw new Exception($"生产订单[{dto.MO.Code}],当前工序[{linedto.MOOperation}]的派工数量不能大于排队数量[{operline.QueueQty}]");
                        }
                    }
                    //if (linedto.RealLaborProcessHours + linedto.RealMachineProcessHours == 0)
                    //{
                    //    throw new Exception($"行号[{linedto.LineNum}],实际工时必须大于0");
                    //}
                }
            }
        }

        /// <summary>
        /// 创建派工完工申报单并审核
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        private static DispatchCompleteOrderDoc CreateComplete(DispatchOrderAITDTOData dto)
        {
			//创建传入DTO
			//单头
            DispatchCompleteOrderAITDTOData dto1 = new DispatchCompleteOrderAITDTOData();
            dto1.DocNo = dto.DocNo;
            dto1.BusinessDate = dto.BusinessDate;
            dto1.ActualStartDate = dto.BusinessDate;
            dto1.ActualEndDate = dto.BusinessDate;
            dto1.DispatchCompleteOrderDocType = dto.DispatchCompleteOrderDocType;
            dto1.DispatchOrder = new CopyOfCommonArchiveDataDTOData() { Code = dto.DocNo };
			dto1.RptWorkCenter = dto.WorkCenter; //工作中心
			//单行
			dto1.DispatchCompleteOrderDocLines = new List<DispatchCompleteOrderDocLineAITDTOData>();
            foreach (var dtoline in dto.DispatchOrderDocLines)
			{
				DispatchCompleteOrderDocLineAITDTOData dtoline1 = new DispatchCompleteOrderDocLineAITDTOData();
				dtoline1.LineNum= dtoline.LineNum;
				dtoline1.DispatchOrderLine = dtoline.LineNum;
				dtoline1.EligibleQty = dtoline.DispatchQty;
				dtoline1.RealLaborPrepareHours= dtoline.RealLaborPrepareHours; //实际人工准备工时
                dtoline1.RealLaborProcessHours= dtoline.RealLaborProcessHours; //实际人工加工工时
                dtoline1.RealMachinePrepareHours= dtoline.RealMachinePrepareHours; //实际机器准备工时
                dtoline1.RealMachineProcessHours= dtoline.RealMachineProcessHours; //实际机器加工工时

                dto1.DispatchCompleteOrderDocLines.Add(dtoline1);
			}

			//调用方法保存单据
            DispatchCompleteOrderDoc doc1 = DispatchCompleteOrderBase.CreateDoc(dto1);
            EntityUtils.UpdateDocNo<DispatchCompleteOrderDoc>(doc1.ID, dto1.DocNo);
            doc1 = DispatchCompleteOrderBase.ApproveDoc(doc1);

			return doc1;
        }
        /// <summary>
        /// 创建派工单并审核
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        private static DispatchOrderDoc CreateDispatch(DispatchOrderAITDTOData dto)
        {
            DispatchOrderDoc doc = DispatchOrderBase.CreateDoc(dto);
            EntityUtils.UpdateDocNo<DispatchOrderDoc>(doc.ID, dto.DocNo);
            doc = DispatchOrderBase.ApproveDoc(doc);
            return doc;
        }
    }

	#endregion
	
	
}